package com.ent.app.bms.web.security.realm;

import javax.annotation.Resource;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import com.ent.app.bms.bean.SysUser;
import com.ent.app.bms.service.system.PermissionService;
import com.ent.app.bms.service.system.RoleService;
import com.ent.app.bms.service.system.UserService;

public class UserRealm extends AuthorizingRealm {

    @Resource(name = "userService")
    private UserService userService;
    @Resource(name = "roleService")
    private RoleService roleService;
    @Resource(name = "permissionService")
    private PermissionService permissionService;

    @Override
    //该方法获得角色、权限等信息,注意SimpleAuthorizationInfo和SimpleAuthenticationInfo的区别
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = (String) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo zationInfo = new SimpleAuthorizationInfo();
        //根据用户名获取角色信息
        zationInfo.setRoles(roleService.findRoleNameSetByUsername(username));
        //根据用户名获取权限信息
        zationInfo.setStringPermissions(permissionService.findPermCodesByusername(username));
        return zationInfo;
    }

    @Override
    // 该方法只获得用户名、盐等信息，真正是在RetryLimitHashedCredentialsMatcher中进行匹配，包含对比密码参数
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken upt = (UsernamePasswordToken)token;
        String username = upt.getUsername();
        SysUser user = userService.findByUsername(username);
        if (user == null) {
            //账号不存在
            throw new UnknownAccountException();
        }
        if (Boolean.TRUE.equals(user.getIsLock())) {
            //帐号锁定
            throw new LockedAccountException(); 
        }
        SimpleAuthenticationInfo cationInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
        cationInfo.setCredentialsSalt(ByteSource.Util.bytes(username+user.getSalt()));
        return cationInfo;
    }

    @Override
    public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
        super.clearCachedAuthorizationInfo(principals);
    }

    @Override
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        super.clearCachedAuthenticationInfo(principals);
    }

    @Override
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }

    public void clearAllCachedAuthorizationInfo() {
        getAuthorizationCache().clear();
    }

    public void clearAllCachedAuthenticationInfo() {
        getAuthenticationCache().clear();
    }

    public void clearAllCache() {
        clearAllCachedAuthenticationInfo();
        clearAllCachedAuthorizationInfo();
    }
}
